/*
 * @Author: ljk
 * @Date: 2023-05-25 16:43:48
 * @LastEditors: ljk
 * @LastEditTime: 2023-05-27 17:08:17
 * @Description: 线程基本操作
 */
#include <iostream>
#include <unistd.h>
#include <pthread.h>

using namespace std;

//线程取消演示
void* threadRun(void* args)
{
    //这种强制类型转换方式自行了解
    const char* name = static_cast<const char*>(args);

    int cnt = 5;
    while (cnt)
    {
        cout << name << " is running " << cnt-- << " obtain self id: " << pthread_self() << endl;
        sleep(1);
    }
    pthread_exit((void*)11);

    //如果线程是被取消而退出的 -- 线程退出码为 PTHREAD_CANCELEDE -- -1
}
//其它线程能取消主线程，线程之间能相互取消吗？？ -- 课后了解
int main()
{
    pthread_t tid;
    pthread_create(&tid, nullptr, threadRun, (void*)"thread 1");
    sleep(3);

    pthread_cancel(tid);

    //线程的分离 -- next lesson
    void* ret = nullptr;
    pthread_join(tid, &ret);
    //这里报错, 精度损失 why? 因为Linux上指针大小是8个字节，int类型是四个字节所以会发生截断导致精度损失故error
    cout << " new thread exit: "<< (int64_t)ret << " quit thread: " << tid << endl;
    return 0;
}

// #define NUM 10

// enum
// {
//     OK = 0,
//     ERROR
// };

// class ThreadData
// {
// public:
//     ThreadData(const string &name, int id, time_t createTime, int top)
//     :_name(name), _id(id), _createTime((uint64_t)createTime), _status(OK), _top(top), _result(0)
//     {}
//     ~ThreadData()
//     {}
// public:
//     //输入的
//     string _name;
//     int _id;
//     uint64_t _createTime;

//     //返回的
//     //例子
//     int _status;
//     int _top;
//     int _result;
//     //如果该线程的作用是排序数组
//     //char arr[n];
// };

// class ResultDate
// {

// };

// // 线程终止
// // 1. 线程函数执行完毕,return void*
// // 2. pthread_exit(void*)
// void *thread_run(void *args)
// {
//     // char *name = (char*)args; //?
//     ThreadData *td = static_cast<ThreadData *>(args);

//     for (int i = 1; i <= td->_top; i++)
//     {
//         td->_result += i;
//     }
//     cout << td->_name << " cal done" << endl;
//     pthread_exit(td);
    
//     // while (true)
//     // {
//     //     cout << "thread is running, name " << td->_name << " create time: " << td->_createTime << " index: " << td->_id << endl;
//     //     // exit(10); // 进程退出，不是线程退出，只要有任何一个线程调用exit，整个进程(所有线程)全部退出！
//     //     // sleep(1);
        
//     //     // break;
//     // }
//     // delete td;

//     // pthread_exit((void*)2);   // void *ret = (void*)1;
//     // return nullptr;
// }
// int main()
// {
//     pthread_t tids[NUM];
//     for (int i = 0; i < NUM; i++)
//     {
//         //主线程main的临时空间被其它进程所共享
//         //char tname[64];

//         //如何避免这种情况的发生呢? 每次将空间开辟在堆上(不共享)
//         char* tname = new char[64];
//         snprintf(tname, 64, "thread-%d", i + 1);
//         ThreadData* td = new ThreadData(tname, i + 1, time(nullptr), 100 + 5 * i);
//         //由于传递的是tname的起始地址所以当其它线程调用的时候tname内容早就被覆盖了(最后一次修改)
//         //不会出现拷贝不完全就回调问题，因为回调函数是要在线程创建完之后再回调
//         pthread_create(tids + i, nullptr, thread_run, td);
//         sleep(1);
//     }

//     //主线程退出，其它进程全部退出(相当于进程退出),新线程创建出来的时候，主线程是需要执行类似等待之类的操作的，不然会导致僵尸进程的问题

//     void* ret = nullptr;

//     for (int i = 0; i < NUM; i++)
//     {
//         //线程等待默认是阻塞的
//         int n = pthread_join(tids[i], &ret);
//         if (n != 0) cerr << "pthread_join error" << endl;
//         ThreadData* td = static_cast<ThreadData*>(ret);
//         if (td->_status == OK)
//         {
//             cout << td->_name << " get [1-" << td->_top << "] result is " <<td->_result << endl;
//         }

//         delete td;
//     }
//     cout << "all thread quit..." << endl;
//     return 0;

//     // while (true)
//     // {
//     //     cout << "main thread running..." << endl;
//     //     sleep(1);
//     // }
//     // return 0;
// }